package cn.melonlib.nars.action.comp.service;

import cn.hutool.core.bean.BeanUtil;
import cn.melonlib.cores.commons.comp.service.impl.WorkerBasicService;
import cn.melonlib.cores.identification.comp.messenger.MessengerUtils;
import cn.melonlib.cores.identification.model.entity.Identification;
import cn.melonlib.cores.identification.model.entity.Organization;
import cn.melonlib.cores.jpa.model.bean.collections.JsonMap;
import cn.melonlib.cores.jpa.model.bean.impl.DefaultQuery;
import cn.melonlib.cores.jpa.model.bean.impl.OffsetQueryImpl;
import cn.melonlib.cores.jpa.model.bean.impl.PaginationList;
import cn.melonlib.cores.model.anno.*;
import cn.melonlib.nars.action.model.entity.ShareNames;
import cn.melonlib.nars.names.comp.service.NamesService;
import cn.melonlib.nars.names.model.entity.MelonDirectory;
import cn.melonlib.nars.names.model.entity.MelonNames;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.intellij.lang.annotations.Language;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.List;

import static cn.melonlib.cores.commons.comp.service.impl.WorkerBasicService.ROOT_METHOD.SAVE;
@WorkerComment("共享资源")
@WorkerService(
        module = "action"
        ,model = @WorkerModel(
                modelType = ShareNames.class
)
        ,ignores = {SAVE}
)
@Service
public class ShareNamesService extends WorkerBasicService<ShareNames> {

    @Resource
    private MessengerUtils messengerUtils;

    @Resource
    private NamesService namesService;

    @WorkerStore
    @WorkerComment("共享文件")
    @Transactional(value = Transactional.TxType.REQUIRED,rollbackOn = Exception.class)
    public ShareNames setShareNames(
            @WorkerParameter(value = "path",comment = "文件路径",required = true) String path,
            @WorkerParameter(value = "time",comment = "共享时间,如果是0或者负数则表示不限制时间(单位毫秒)",required = true) Long time,
            @WorkerParameter(value = "extractCode",comment = "是否需要提取码",required = true) boolean extractCode,
            @WorkerParameter(value = "disclosure", comment = "是否完全公开(访问是否需要登陆)",required = true) boolean disclosure
            )throws Exception{
        MelonNames names=namesService.lookup(path);
        Assert.isTrue(!(names instanceof MelonDirectory),"目录不能共享");
        @Language("HQL") String query="from ShareNames where path=?1 and creatorId=?2 and tenantId=?3 and expire>?4";
        Identification identification= getIdentificationMessenger().getIdentification();
        Organization organization=getIdentificationMessenger().getOrganization();
        List<ShareNames> shareNamesList= dao.<List<ShareNames>,DefaultQuery>search(new DefaultQuery(query,
                List.of(path, BeanUtil.getProperty(identification,"id"),
                        BeanUtil.getProperty(organization,"id"),
                        System.currentTimeMillis()))).getResult();
        ShareNames shareNames=shareNamesList.isEmpty()?new ShareNames():shareNamesList.get(0);
        shareNames.setPath(names.getPath());
        shareNames.setNamesId(names.getId());
        if(time>0){
            shareNames.setExpire(System.currentTimeMillis()+time);
        }
        if(extractCode){
            shareNames.setExtractCode(RandomStringUtils.random(RandomUtils.nextInt(5,10),"1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"));
        }
        shareNames.setDisclosure(disclosure);
        messengerUtils.setMessengers(shareNames);
        return shareNames;
    }

    @WorkerQuery
    @WorkerComment("获取共享文件")
    public ShareNames shareNames(@WorkerParameter(value = "path",comment = "文件路径",required = true) String path){
        MelonNames names=namesService.lookup(path);
        Assert.notNull(names,"未找到共享文件");
        @Language("HQL") String query="from ShareNames where path=?1 and creatorId=?2 and tenantId=?3 and expire>?4";
        Identification identification= getIdentificationMessenger().getIdentification();
        Organization organization=getIdentificationMessenger().getOrganization();
        List<ShareNames> shareNamesList= dao.<List<ShareNames>,DefaultQuery>search(new DefaultQuery(query,
                List.of(path,BeanUtil.getProperty(identification,"id"),
                        BeanUtil.getProperty(organization,"id"),
                        System.currentTimeMillis()))).getResult();
        Assert.notEmpty(shareNamesList,"未找到共享文件");
        return shareNamesList.get(0);
    }

    @WorkerComment("获取当前共享的所有文件")
    @WorkerQuery
    public PaginationList<ShareNames> myShareNamesList(
            @WorkerParameter(value = "first",comment = "数据量",required = true) Integer first,
            @WorkerParameter(value = "offset",comment = "偏移量",required = true) Long offset
    ){
        Identification identification= getIdentificationMessenger().getIdentification();
        Organization organization= getIdentificationMessenger().getOrganization();
        return dao.<PaginationList<ShareNames>,OffsetQueryImpl>search(new OffsetQueryImpl(ShareNames.class, JsonMap.<JsonMap<Object>>createMap()
                .append("creatorId",JsonMap.createMap().append("eq",BeanUtil.getProperty(identification,"id")))
                .append("tenantId",JsonMap.createMap().append("eq",BeanUtil.getProperty(organization,"id")))
                .append("expire",JsonMap.createMap().append("gt",System.currentTimeMillis()))
                ,offset,first)).getResult();
    }
}
